package com.fita.admin.web.controller.order;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.page.Page;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.persistence.annotation.Dao;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.utils.WebUtils;
import com.fita.admin.dao.OrderDao;
import com.fita.admin.entity.search.order.OrderSearch;
import com.fita.admin.entity.security.Login;
import com.fita.admin.handler.SmsHandler;
import com.fita.admin.service.DataService;
import com.fita.admin.service.coupon.CouponService;
import com.fita.admin.service.data.OrderSpecialEquipmentService;
import com.fita.admin.service.order.OrderService;
import com.fita.admin.web.resolver.Secure;
import com.fita.entity.coupon.Coupon;
import com.fita.entity.order.Order;
import com.fita.entity.order.OrderComponent;
import com.fita.entity.order.OrderSpecialEquipment;
import com.fita.entity.order.OrderStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 订单管理
 *
 * @author Ark
 */
@Controller
@RequestMapping("/orders")
@MenuSetting("menu-order")
public class OrderController {

    private static final Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private CouponService<Coupon> couponService;

    @Autowired
    private OrderService orderService;

    @Dao
    private OrderDao orderDao;

    @Autowired
    private OrderSpecialEquipmentService orderSpecialEquipmentService;

    @Autowired
    @Qualifier("dataService")
    private DataService<Order> ordersService;

    @Autowired
    private SmsHandler smsHandler;

    /**
     * list
     *
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-order-list")
    public ModelAndView list(@RequestParam(name = "status", defaultValue = "UNPAID") OrderStatus status, @Secure Login login, Page page, HttpServletRequest request) {

        ModelAndView modelAndView = new ModelAndView("order/order-list");
        int totals = orderService.count(login, status);
        modelAndView.addObject("status", status);

        if (totals > 0) {

            List<Order> order = orderService.list(login, status, page.with(totals));
            modelAndView.addObject("order", order);
            modelAndView.addObject("page", page);

        }
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "filter", "page"));

        return modelAndView;
    }


    /**
     * 打开查询面板
     *
     * @return
     */
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @MenuSetting("submenu-order-list")
    public ModelAndView search(@RequestParam("status") OrderStatus status) {

        ModelAndView modelAndView = new ModelAndView("order/order-search");
        modelAndView.addObject("status", status);

        return modelAndView;
    }

    /**
     * @param login
     * @param search
     * @param request
     * @param page
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-order-list")
    @ResponseBody
    public ModelAndView onSearch(@RequestParam("status") OrderStatus status, @Secure Login login, OrderSearch search, HttpServletRequest request, Page page) {

        ModelAndView modelAndView = new ModelAndView("order/order-list");
        modelAndView.addObject("status", status); // Status from search object

        int totals = orderService.count(login, Order.class, search.getPreparedFilter(false));

        if (totals > 0) {
            List<Order> order = orderService.search(login, Order.class, search, page.with(totals));
            modelAndView.addObject("order", order);
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page", "filter"));
        }

        return modelAndView;
    }

    /**
     * 标记已支付面板
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/pay", method = RequestMethod.GET)
    @MenuSetting("submenu-order-list")
    public ModelAndView pay(@PathVariable Long id,
                            @Secure Login login) {

        ModelAndView modelAndView = new ModelAndView("order/order-pay");

        modelAndView.addObject("id", id);

        return modelAndView;
    }

    /**
     * 标记已支付
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/pay", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public HttpResult onPay(@PathVariable Long id, OrderComponent orderComponent, @Secure Login login) {

        HttpResult httpResult = new HttpResult();
        try {
            orderService.pay(id, orderComponent, login.getId());

            httpResult.success().message("标记支付成功");

        } catch (BusinessException e) {

            logger.error("#onPay() occurs error", e);

            httpResult.fail(e.getCode()).message(e.getMessage());

        } catch (Exception e) {

            logger.error("#onPay() occurs error", e);

            httpResult.fail("500").message("标记支付失败");
        }


        //coupon 状态改成 已使用
        couponService.useCoupon(id);

        return httpResult;

    }

    /**
     * 打开核销面板
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/consumed", method = RequestMethod.GET)
    @MenuSetting("submenu-order-list")
    public ModelAndView consumed(@PathVariable Long id) {

        ModelAndView modelAndView = new ModelAndView("order/order-consumed");
        modelAndView.addObject("id", id);

        return modelAndView;

    }

    /**
     * 核销
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/consumed", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public HttpResult onConsumed(@PathVariable Long id) {

        HttpResult httpResult = new HttpResult();

        try {
            orderService.consumed(id);
            httpResult.success().message("标记已核销成功");
        } catch (Exception e) {
            logger.error("onConsumed occurs error", e);
            httpResult.fail("500").message("标记已核销失败");
        }

        return httpResult;
    }

    /**
     * 标记已退款
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/refunded", method = RequestMethod.GET)
    public ModelAndView refunded(@PathVariable Long id) {

        ModelAndView modelAndView = new ModelAndView("order/order-refunded");
        return modelAndView;
    }

    /**
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/refunded", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public HttpResult onRefunded(@PathVariable Long id) {

        HttpResult httpResult = new HttpResult();
        try {
            orderService.refunded(id);
            httpResult.success().message("标记已退款成功");
        } catch (Exception e) {
            logger.error("onRefunded occurs error", e);
            httpResult.fail("500").message("标记已退款失败");
        }

        return httpResult;
    }

    /**
     * 打开取消订单面板
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/cancel", method = RequestMethod.GET)
    @MenuSetting("submenu-order-list")
    public ModelAndView cancel(@PathVariable Long id) {

        ModelAndView modelAndView = new ModelAndView("order/order-cancel");
        modelAndView.addObject("id", id);

        return modelAndView;

    }

    /**
     * 取消订单
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/cancel", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public HttpResult onCancel(@PathVariable Long id) {

        HttpResult httpResult = new HttpResult();

        try {

            Order order = orderService.load(Order.class, id);

            orderService.cancel(id);

            boolean send = smsHandler.sendOrderCancelMessage(order.getCustomerMobile(), order.getAlamoCode(), "/cars/search");

            if (send == false) {

                logger.error("onCancel sendOrderCancelMessage occurs error");
            }
            httpResult.success().message("取消订单成功");

            //优惠券 order 重置为NULL
            couponService.resetCoupon(order);


        } catch (BusinessException e) {
            logger.error("onCancel occurs error", e);
            httpResult.fail(e.getCode()).message(e.getMessage());
        } catch (Exception e) {
            logger.error("onCancel occurs error", e);
            httpResult.fail("500").message("取消订单失败");
        }

        return httpResult;
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @MenuSetting("submenu-order-list")
    public ModelAndView view(@PathVariable Long id) {

        ModelAndView modelAndView = new ModelAndView("order/order-view");
        Order order = orderService.load(Order.class, id);
        List<OrderSpecialEquipment> orderSpecialEquipment = orderSpecialEquipmentService.list(id);
        modelAndView.addObject("orderSpecialEquipment", orderSpecialEquipment);
        modelAndView.addObject("order", order);

        logger.trace("test");

        return modelAndView;
    }


}
